כתבתי קוד כזה ויש לי שגיאה :

Fatal error: Cannot redeclare static Father::$prop as non static child::$prop in C:\xampp\htdocs\7.objects\in2.php on line 10

ולא הבנתי מה הבעיה בדיוק בקוד

class Father{
    static public $prop = 'Hi!';
}

class child extends Father{  
     public $prop = 'Moti';  

}

echo Father::$prop;

תודה לעוזרים ולמסבירים !

10 תשובות

avatar ענה intval ב 15 ליולי 2015 #

המילה static אומרת שזה מקום בזיכרון שמשותף לכל המופעים.
הגדרת את המאפיין prop בתור משותף לכל המופעים במחלקת father
ואז במחלקה היורשת ניסית לדרוס את המאפיין שהגדרת במחלקת האב עם ערך חדש, אך בלי לרשום שהוא משותף לכל המופעים.
לכן יש ניגוד בין מחלקת האב לבין מחלקת הילד: במחלקה האב המאפיין מוגדרת כמשותף לכל המופעים ובמחלקת הילד הוא לא מוגדר ככזה.

PHP אומרת לך בשגיאה הזו שבמחלקת הילד אפשר לדרוס ערך של מאפיין, אך אי אפשר לשנות את הייחוס שלו (האם משותף לכל המופעים או לא)

מכאן שאתה יכול או להוריד את ה-static ממחלקת האב, או להוסיף static במחלקה היורשת

avatar ענה mot10 ב 15 ליולי 2015 #

תודה על התשובה הבנתי מה כתבת ועכשיו עשיתי בשניהם static
אבל אני לא מבין משהו אחד: אם אני באמת דורס את המאפיין ולא משנה לו את הייחוס, אלא משאיר אותו כ static
אז איך זה יכול להיות שאם לאחר מכן אני פונה ישירות ל prop שבמחלקת האב, אז הוא מחזיר לי Hi ?
הרי הוא אמור להחזיר לי Moti כי הרי לפני שניה הוא נדרס ( ע"י מחלקת הבן )
וגם הסברת ש static זה מקום אחד בזיכרון שמשותף לכולם. אז אם אני משנה את אותו מקום זיכרון לערך אחר, אז הוא אמור להיות מעכשיו עם הערך האחר
ושניתי אותו במחלקת הבן
זה קטע שקשה לי שלא הצלחתי להבין אותו עדיין..

זה הקוד של עכשיו :

class Father{
    static public $prop = 'Hi!';
}

class child extends Father{  
    static public $prop = 'Moti';  

}


echo child::$prop; // Mooti
echo '<p>';
echo Father::$prop; // Hi!

תודה על התשובה !

avatar ענה Splash ב 15 ליולי 2015 #

הוא לא דורס אותו,על מנת שהוא ידרוס אותו אתה צריך להגדיר שיהיה ביניהם יחס מסוים משהו בסגנון הזה -

class Father
{
    static public $prop = "Mooti";
}

class child extends Father
{
    function __construct()
    {
        self::$prop = "Hi!";
    }
   
}


echo Father::$prop; // Mooti
echo '<p>';
new child();
echo Father::$prop; // Hi!


בקוד שאתה עשית לא גרמת לשום שינוי במחלקה Father והשינוי קורא רק במידה והאוביקט יהיה מסוג child.[הגדרת את המשתנה מחדש]

avatar ענה mot10 ב 15 ליולי 2015 #

אז אם הגדרתי את אותו משתנה מחדש אז הוא אמור להיות עם הערך החדש - Moti. לא ?
זה בדיוק מה שאני לא מצליח להבין
הרי אמרנו שהוא משתנה סטטי שנמצא פעם אחת בזיכרון ומחלקת child ירשה אותו בדיוק כמו שהוא (אפילו בלי לשנות לו את ה Property Visibility)
אז אם אני יוצר עכשיו אובייקט כמו שאמרת כמובן. למה זה לא ישתנה ל Moti ?

avatar ענה intval ב 16 ליולי 2015 #

בדיוק כפי splash אמר, למרות שהקוד הזה נראה תקין, הוא לא באמת דורס (או משנה את הערך) בגלל שמדובר בשני "תאים שונים בזיכרון".
הראשון משותף לכל המחלקות מסוג Father והתא השני משותף לכל המחלקות מסוג Child, לכן אין בינהם ממש דריסה, כפי שיש בדרך כלל בין ילד לאב.

avatar ענה mot10 ב 16 ליולי 2015 #

תודה רבה הבנתי מה אתה אומר אבל אני לא מבין עדיין משהו
שכשאתה מצהיר מחדש עם Property Visibility יותר מאובטח ממה שהוא מוגדר במחלקת האב כלומר כך:

class Father{
    static protected $prop = 'Hi!';
}

class child extends Father{  
    static private $prop = 'Moti';  
}

אז על המקום אתה מקבל Fatal eroor שאומר שאתה לא יכול להתייחס לאותו משתנה שירשת. ולשנות לו Visibility ליותר מאובטח: כך השגיאה הזאת נראית :
Fatal error: Access level to child::$prop must be protected (as in class Father) or weaker in C:\xampp\htdocs\7.objects\practice\index.php on line 8

כלומר אני מבין שהוא מדבר על אותו משתנה בדיוק שמוגדר לי במחלקת האב
אז למה כשאני לא יגע בו בכלל ב Visibility. וישאיר אותו כמו שהוא (protected) ויגדיר לו רק ערך חדש, אז הוא לא ישתנה לערך החדש
אלא הוא יצור משתנה חדש כמו שאמרת

avatar ענה intval ב 16 ליולי 2015 #

כי בתכלס מדובר לא על "אותו משתנה בדיוק"
אלא על שני תאים בזיכרון שיש להם אותו שם והמחשב מחליט מאיזה מהם לקרוא על בסיס מאיפה אתה מנסה לגשת אליו, מתוך מחלקת האב או מתוך מחלקת הילד.
כשאתה משנה מ public ל private, אתה משנה את הגישה לפי שם
כשאתה משנה מ static ללא static, אתה משנה את התא בזיכרון שאליו השם משתנה הזה מוביל

avatar ענה intval ב 16 ליולי 2015 #

עכשיו קראתי את ההודעה שלי והבנתי שניסיתי להסביר אין עובד מקרה מוזר שאם ראש צוות טוב היה רואה בפרויקט שלו, הוא היה חייב לשבור למפתח את המקלדת. בתור לנסות להבין מה הולך פה - זה אחלה תרגיל, אבל תנסה להימנע כמה שאפשר ממקרים כאלה (ובהחלט אפשר)

avatar ענה mot10 ב 17 ליולי 2015 #

אני עדיין לא עובד בתחום חח הלוואי היה לי עבודה בזה
אני עדיין לומד וזה תרגיל הבנה בשבילי
אני רוצה פשוט להבין את הלוגיקה מאחורי הקלעים וזה קטע שאני עדיין תקוע בהבנה שלו
ואני אשמח מאוד אם תסביר לי את זה יותר ברור
כי האמת שאני לא בטוח שהבנתי את התשובה שלך ..

avatar ענה Splash ב 17 ליולי 2015 #

תאורטית היה אפשר לעשות שתוכל להגדיר משתנה באב כסטטי ובבן כלא סטטי אבל זה לא נכון. אם כל הייחוס של המשתנה שונה אתה פשוט יוצר בלבול בקוד והרבה יותר נכון יהיה ליצור משתנה חדש.
כנל לגבי הכימוס,ברגע שאתה משנה את המשתנה ליותר "מאובטח" אתה עלול לגרום לבעיות בקוד ולכן המנוע של php לא מאפשר לך לעשות את זה.
הרעיון של המחלקות "בן" זה תקח את מה שיש לאבא להציע - ותרחיב אותו.
ברגע שאתה אומר לו "שומע ? אני רוצה רק את א,ב,ג של האבא אבל בלי ד" זה לא אפשרי,הבן מכיל את כל הנתונים של האבא ויותר מכך